package org.goldenport.g3.messages

import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import java.io.InputStream
import sql.SqlUtil.{symbol2name => sql_name, value2literal => sql_literal}
import org.goldenport.util.QSymbol

/**
 * @since   Aug. 13, 2010
 * @version Aug. 30, 2010
 * @author  ASAMI, Tomoharu
 **/
abstract class Expression {
  def sqlLiteral(target: Symbol): String
  def sqlLiteral: String
}

class Id(val value: Any, val idName: Symbol = 'id) extends Expression {
  def sqlLiteral(target: Symbol) = sql_name(target) + " = " + sql_literal(value)
  def sqlLiteral = sqlLiteral(idName)
}

object Id {
  def apply(id: Any) = new Id(id)

  def apply(idname: Symbol, id: Any) = new Id(id, idname)

//  implicit def symbol2String(symbol: Symbol): String = symbol.name
}

class Attr(val name: Symbol) extends Expression {
  def sqlLiteral(target: Symbol) = sql_name(target)
  def sqlLiteral = sqlLiteral(name)

  def ===(value: Any): AttrEqual = new AttrEqual(name, value)

  def equal(value: Any): AttrEqual = new AttrEqual(name, value)

  def >(value: Any): AttrGreaterThan = new AttrGreaterThan(name, value)

  def <(value: Any): AttrLessThan = new AttrLessThan(name, value)

  def >=(value: Any): AttrGreaterEqualThan = new AttrGreaterEqualThan(name, value)

  def <=(value: Any): AttrLessEqualThan = new AttrLessEqualThan(name, value)

  def #==(value: Any): AttrEqual = new AttrEqual(name, value)

  def #>(value: Any): AttrGreaterThan = new AttrGreaterThan(name, value)

  def #<(value: Any): AttrLessThan = new AttrLessThan(name, value)

  def #>=(value: Any): AttrGreaterEqualThan = new AttrGreaterEqualThan(name, value)

  def #<=(value: Any): AttrLessEqualThan = new AttrLessEqualThan(name, value)
}

class AttrEqual(val name: Symbol, val value: Any) extends Expression {
  def sqlLiteral(target: Symbol) = sql_name(target) + " = " + sql_literal(value)
  def sqlLiteral = sqlLiteral(name)
}

class AttrGreaterThan(val name: Symbol, val value: Any) extends Expression {
  def sqlLiteral(target: Symbol) = sql_name(target) + " > " + sql_literal(value)
  def sqlLiteral = sqlLiteral(name)
}

class AttrLessThan(val name: Symbol, val value: Any) extends Expression {
  def sqlLiteral(target: Symbol) = sql_name(target) + " < " + sql_literal(value)
  def sqlLiteral = sqlLiteral(name)
}

class AttrGreaterEqualThan(val name: Symbol, val value: Any) extends Expression {
  def sqlLiteral(target: Symbol) = sql_name(target) + " >= " + sql_literal(value)
  def sqlLiteral = sqlLiteral(name)
}

class AttrLessEqualThan(val name: Symbol, val value: Any) extends Expression {
  def sqlLiteral(target: Symbol) = sql_name(target) + " <= " + sql_literal(value)
  def sqlLiteral = sqlLiteral(name)
}

object Attr {
  def apply(name: Symbol) = new Attr(name)
}

class EntityReference(val uri: String) extends Expression {
  def sqlLiteral(target: Symbol) = error("")
  def sqlLiteral = error("")
}

object EntityReference {
  def apply(uri: String) = new EntityReference(uri)
}

class EntityReferenceAttribute(val entity: QSymbol, val valueAttribute: Symbol, val keyAttribute: Symbol, val refAttribute: Symbol) extends Expression {
  def sqlLiteral(target: Symbol) = error("")
  def sqlLiteral = error("")
}

object EntityReferenceAttribute {
  def apply(entity: QSymbol, valueAttribute: Symbol, keyAttribute: Symbol, refAttribute: Symbol) = new EntityReferenceAttribute(entity, valueAttribute, keyAttribute, refAttribute)
}
